package com.tanglon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanglon.constants.SystemConstants;
import com.tanglon.domain.ResponseResult;
import com.tanglon.domain.dto.AddArticleDTO;
import com.tanglon.domain.dto.UpdateArticleDetailDTO;
import com.tanglon.domain.entity.Article;
import com.tanglon.domain.entity.ArticleTag;
import com.tanglon.domain.entity.Tag;
import com.tanglon.domain.vo.*;
import com.tanglon.enums.AppHttpCodeEnum;
import com.tanglon.mapper.ArticleMapper;
import com.tanglon.mapper.ArticleTagMapper;
import com.tanglon.service.ArticleService;
import com.tanglon.service.ArticleTagService;
import com.tanglon.service.CategoryService;
import com.tanglon.utils.BeanCopyUtils;
import com.tanglon.utils.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Autowired
    private CategoryService categoryService;
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ArticleTagService articleTagService;
    @Autowired
    private ArticleTagMapper articleTagMapper;

    @Autowired
    private ArticleMapper articleMapper;

    /**
     * 查询热门文章
     * @return
     */
    @Override
    public ResponseResult hotArticleList() {
        // TODO 用redis的zset设置排行榜 根据zset的排序查前十的文章再查信息
        Map<String, Double> rangeDesc = redisCache.getSortedSetRangeDesc(SystemConstants.ARTICLE_RAND, 1, 10);

        // 遍历所有键值对
        List<HotArticleVo> hotArticleVos = new ArrayList<>();
        for (Map.Entry<String, Double> entry : rangeDesc.entrySet()) {
            // 获取文章ID
            Long articleId = Long.parseLong(entry.getKey());
            // 获取浏览量
            Long viewCount = entry.getValue().longValue();
            Article article = articleMapper.selectById(articleId);
            article.setViewCount(viewCount);
            HotArticleVo hotArticleVo = BeanCopyUtils.copyBean(article, HotArticleVo.class);
            hotArticleVos.add(hotArticleVo);
        }
        //查询热门文章
        /*LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<Article>();
        queryWrapper.in(Article::getId, articleIdList)
                // 可以添加其他过滤条件，如只查询已发布的文章
                .eq(Article::getStatus, 0); // status字段，0表示已发布
        //必须是正式文章
        queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        //按照浏览量进行排序
        queryWrapper.orderByDesc(Article::getViewCount);
        //分页查询第一页的10条数据
        Page<Article> page = new Page<>(1, 10);
        page(page,queryWrapper);
        List<Article> articles = page.getRecords();*/

        return ResponseResult.okResult(hotArticleVos);

    }

    /**
     * 分页查询文章 根据分类id
     * @param pageNum
     * @param pageSize
     * @param categoryId
     * @return
     */
    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        //查询条件
        LambdaQueryWrapper<Article> lambdaQueryWrapper =new LambdaQueryWrapper<>();

        //注意categoryId可能为空
        lambdaQueryWrapper.eq(Objects.nonNull(categoryId)&&categoryId>0,Article::getCategoryId,categoryId);

        //状态是已发布
        lambdaQueryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);

        //对isTop进行降序
        lambdaQueryWrapper.orderByDesc(Article::getIsTop);

        //分页查询
        Page<Article> page = new Page<>(pageNum, pageSize);
        page(page, lambdaQueryWrapper);

        //查询categoryName
        List<Article> articles = page.getRecords();
        articles=articles.stream()
                .map(article -> {
                    //从redis获取浏览量
                    Integer viewCount = redisCache.getCacheMapValue(SystemConstants.ARTICLE_VIEWCOUNT, article.getId().toString());
                    article.setViewCount(viewCount.longValue());
                    //获取分类id，查询分类信息
                    article.setCategoryName(categoryService.getById(article.getCategoryId()).getName());
                    return article;
                })
                .collect(Collectors.toList());

        //封装查询结果
        List<ArticleListVo> articleListVos=BeanCopyUtils.copyBeanList(articles, ArticleListVo.class);
        PageVo pageVo=new PageVo();
        pageVo.setRows(articleListVos);
        pageVo.setTotal(page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    /**
     * 获取文章详情
     * @param id
     * @return
     */
    @Override
    public ResponseResult getArticleDetail(Long id) {
        //根据id获取文章数据
        Article article=this.getById(id);
        //从redis获取浏览量
        Integer viewCount = redisCache.getCacheMapValue(SystemConstants.ARTICLE_VIEWCOUNT, id.toString());
        //设置分类名称
        article.setCategoryName(categoryService.getById(article.getCategoryId()).getName());
        article.setViewCount(viewCount.longValue());
        //封装数据到Vo
        ArticleDetailVo vo=BeanCopyUtils.copyBean(article, ArticleDetailVo.class);
        System.out.println("返回文章详情视图："+vo);
        return ResponseResult.okResult(vo);
    }

    /**
     * 浏览量增加
     * @param id
     * @return
     */
    @Override
    public ResponseResult updateViewCount(Long id) {

        redisCache.incrementCacheMapValue(SystemConstants.ARTICLE_VIEWCOUNT,id.toString(),1);
        //  redis的排行榜对应的也要增加
        redisCache.incrementSortedSetScore(SystemConstants.ARTICLE_RAND,id.toString(),1);
        return ResponseResult.okResult();
    }

    /**
     * 写博文
     * @param addArticleDTO
     * @return
     */
    @Override
    @Transactional
    public ResponseResult add(AddArticleDTO addArticleDTO) {
        //先存文章信息
        Article article = BeanCopyUtils.copyBean(addArticleDTO, Article.class);
        save(article);

        //将标签信息存入article_tag表中
        List<ArticleTag> collect = addArticleDTO.getTags().stream()
                .map(tagId -> new ArticleTag(addArticleDTO.getId(), tagId))
                .collect(Collectors.toList());
        //添加 博客和标签的关联
        articleTagService.saveBatch(collect);
        return ResponseResult.okResult();
    }

    /**
     * 后台获取文章列表
     * @param pageNum
     * @param pageSize
     * @param title
     * @param summary
     * @return
     */
    @Override
    public ResponseResult<PageVo> getlist(Integer pageNum, Integer pageSize, String title, String summary) {
        LambdaQueryWrapper<Article> lambdaQueryWrapper =new LambdaQueryWrapper<>();
        //模糊条件查询
        lambdaQueryWrapper.like(StringUtils.hasText(title),Article::getTitle,title);
        lambdaQueryWrapper.like(StringUtils.hasText(summary),Article::getSummary, summary);

        //分页查询记录
        Page<Article> page = new Page<>(pageNum, pageSize);
        page(page, lambdaQueryWrapper);
        //封装数据
        List<Article> articles=page.getRecords();
        List<AdminArticleListVo> adminArticleListVos = BeanCopyUtils.copyBeanList(articles, AdminArticleListVo.class);
        PageVo pageVo=new PageVo();
        pageVo.setRows(adminArticleListVos);
        pageVo.setTotal(page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    /**
     * 获取文章详情
     * @param id
     * @return
     */
    @Override
    public ResponseResult getDetail(Long id) {
        Article article=this.getById(id);
        //判断是否article是否为null
        if(article==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR);
        }

        List<Long> tags=articleTagMapper.getTagId(id);
        AdminArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article, AdminArticleDetailVo.class);
        //根据文章id查询
        articleDetailVo.setTags(tags);



        return ResponseResult.okResult(articleDetailVo);
    }

    /**
     * 修改文章详情
     * @param updateArticleDetailDTO
     * @return
     */
    @Override
    @Transactional
    public ResponseResult updateDetail(UpdateArticleDetailDTO updateArticleDetailDTO) {
        // TODO 后期只有超级管理员才能修改其创建人修改人浏览量这些
        //文章信息
        Article article = BeanCopyUtils.copyBean(updateArticleDetailDTO, Article.class);
        updateById(article);

        //标签信息
        //List<Long> tags = updateArticleDetailDTO.getTags();
        List<ArticleTag> tagList = updateArticleDetailDTO.getTags().stream()
                .map(tagId -> new ArticleTag(updateArticleDetailDTO.getId(), tagId))
                .collect(Collectors.toList());
        //标签先删原有的
        LambdaQueryWrapper<ArticleTag> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArticleTag::getArticleId, article.getId());
        articleTagMapper.delete(queryWrapper);
        if(tagList != null && tagList.size() > 0){
            tagList.forEach(tag -> {
                articleTagMapper.insert(tag);
            });
        }
        return ResponseResult.okResult();
    }

    /**
     * 删除文章(逻辑删除)
     * @param id
     * @return
     */
    @Override
    public ResponseResult deleleArticle(Long id) {
        //根据文章id逻辑删除文章
        // 创建更新对象，设置删除标志为1（已删除）
        Article article = new Article();
        article.setId(id.longValue());  // 注意表中id是bigint类型
        article.setDelFlag(1);
        // 执行更新操作（逻辑删除）
        boolean updateResult = updateById(article);
        if(updateResult){
            //需要把缓存的也删了
            redisCache.delCacheMapValue(SystemConstants.ARTICLE_VIEWCOUNT,id.toString());
            // TODO zset的也要删除
            redisCache.removeFromSortedSet(SystemConstants.ARTICLE_RAND,id.toString());
            return ResponseResult.okResult();
        }else{
            return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR);
        }

    }


    /**
     * 使用MyBatis Plus的saveBatch方法批量插入
     */
    @Transactional(rollbackFor = Exception.class)
    public void generateTestArticlesWithSaveBatch(int count, int batchSize) {
        List<Article> articles = new ArrayList<>();
        long startTime = System.currentTimeMillis();

        for (int i = 1; i <= count; i++) {
            Article article = createArticle(i);
            articles.add(article);
        }

        // 使用saveBatch方法批量插入
        boolean result = saveBatch(articles, batchSize);

        long endTime = System.currentTimeMillis();
        log.info("使用saveBatch插入 {} 条数据，耗时: {} ms，结果: {}",
                count, (endTime - startTime), result);
    }

    private Article createArticle(int index) {
        Article article = new Article();
        article.setTitle("测试文章" + index);
        article.setContent("这是测试文章" + index + "的详细内容。");
        article.setSummary("测试文章摘要" + index);
        article.setCategoryId(15L);
        article.setStatus("0");
        article.setCreateBy(1L);
        article.setCreateTime(new Date());
        article.setViewCount((long) (Math.random() * 101)); // 0-100随机浏览量
        article.setIsTop(index % 50 == 0 ? "1" : "0");
        article.setIsComment("1");
        article.setDelFlag(0);
        return article;
    }
}
